<template>
  <div>
    <div class="navBar">
      <van-nav-bar
        title="游戏开始"
        left-text="返回"
        left-arrow
        right-text="重来"
        @click-right="handleReset"
        @click-left="beginClickBg(), $router.go(-1)" />
    </div>
    <div class="time">{{ dayjs(time * 1000).format("mm:ss") }}</div>
    <div class="type GridRange">网格类型：{{ range + " x " + range }}</div>
    <div class="type GridLevel">游戏难度：{{ level + "%" }}</div>
    <div class="container">
      <div class="row" v-for="(item1, index1) in range" :key="index1">
        <div class="col" v-for="(item2, index2) in range" :key="index2">
          <Grid
            ref="ge"
            :x="index1"
            :y="index2"
            :isPointer="isPointer"
            :isEnd="isEnd"
            @handleDfs="handleDfs"
            @judgeEnd="judgeEnd"
            @handleEnd="handleEnd"
            @addMine="addMine"
            @addComplete="addComplete"></Grid>
        </div>
      </div>
    </div>
    <div class="btnBox">
      <div
        :class="['btn', 'pointer', isPointer ? 'active' : '']"
        @click="beginClickBg(), (isPointer = true)">
        <van-icon name="guide-o" />
      </div>
      <div
        :class="['btn', 'flag', isPointer ? '' : 'active']"
        @click="beginClickBg(), (isPointer = false)">
        <van-icon name="flag-o" />
      </div>
    </div>
    <van-dialog
      v-model="show"
      title="游戏结束"
      show-cancel-button
      confirmButtonColor="#409eff"
      cancelButtonText="再来一局"
      @confirm="beginClickBg()"
      @cancel="handleReset">
      <div class="dialogInfo">网格类型：{{ range + " x " + range }}</div>
      <div class="dialogInfo">游戏难度：{{ level + "%" }}</div>
      <div class="dialogInfo">用时：{{ dayjs(time * 1000).format("mm:ss") }}</div>
      <div class="dialogInfo">
        完成度：{{ ((complete * 100) / (range * range - mine)).toFixed(2) + "%" }}
      </div>
    </van-dialog>
  </div>
</template>

<script>
import Grid from "./Grid";
import dayjs from "dayjs";
import { mapState, mapMutations } from "vuex";
export default {
  components: { Grid },
  data() {
    return {
      isEnd: false,
      time: 0,
      timer: null,
      dialogVisible: false,
      complete: 0,
      mine: 0,
      show: false,
      isPointer: true,
    };
  },
  methods: {
    dayjs,
    ...mapMutations("record", ["addRecord"]),
    ...mapMutations("audio", ["beginClickBg"]),
    reset() {
      this.isEnd = false;
      this.time = 0;
      this.timer = null;
      this.complete = 0;
      this.mine = 0;
      let arr = this.$refs.ge;
      arr.forEach((item) => {
        item.reset();
      });
    },
    init() {
      let arr = this.$refs.ge;
      for (let i = 0; i < arr.length; i++) {
        if (arr[i].isMine) continue;
        for (let j = -1; j <= 1; j++) {
          for (let k = -1; k <= 1; k++) {
            if (
              arr[i].x + j < 0 ||
              arr[i].x + j >= this.range ||
              arr[i].y + k < 0 ||
              arr[i].y + k >= this.range
            )
              continue;
            if (arr[this.range * (arr[i].x + j) + arr[i].y + k].isMine) arr[i].value++;
          }
        }
      }
      this.timer = setInterval(() => {
        this.time++;
      }, 1000);
    },
    handleReset() {
      this.beginClickBg();
      this.reset();
      this.init();
    },
    addComplete() {
      this.complete++;
    },
    addMine() {
      this.mine++;
    },
    addData() {
      let obj = {
        id: this.$store.state.record.len + 1,
        username: "玩家",
        gridType: this.range + " x " + this.range,
        gameLevel: this.level + "%",
        time: dayjs(this.time * 1000).format("mm:ss"),
        date: dayjs().format("YYYY-MM-DD HH:mm:ss"),
        complete: ((this.complete * 100) / (this.range * this.range - this.mine)).toFixed(2) + "%",
        isSuccess: this.complete == this.range * this.range - this.mine ? true : false,
      };
      this.addRecord(obj);
    },
    handleDfs(x, y) {
      let idx = this.range * x + y;
      let arr = this.$refs.ge;
      if (arr[idx].isDfs) return;
      arr[idx].isDfs = true;
      if (!arr[idx].isMine) {
        arr[idx].handleClick();
        if (arr[idx].value == 0) {
          if (x - 1 >= 0) this.handleDfs(x - 1, y);
          if (x + 1 < this.range) this.handleDfs(x + 1, y);
          if (y - 1 >= 0) this.handleDfs(x, y - 1);
          if (y + 1 < this.range) this.handleDfs(x, y + 1);
          if (x - 1 >= 0 && y - 1 >= 0) this.handleDfs(x - 1, y - 1);
          if (x - 1 >= 0 && y + 1 < this.range) this.handleDfs(x - 1, y + 1);
          if (x + 1 < this.range && y - 1 >= 0) this.handleDfs(x + 1, y - 1);
          if (x + 1 < this.range && y + 1 < this.range) this.handleDfs(x + 1, y + 1);
        }
      }
    },
    handleEnd() {
      this.isEnd = true;
      clearInterval(this.timer);
      if (this.recordFail) this.addData();
      setTimeout(() => {
        this.show = true;
      }, 10);
    },
    judgeEnd() {
      let arr = this.$refs.ge;
      let flag = false;
      arr.forEach((item) => {
        if (!item.isMine && !item.flag) flag = true;
      });
      if (!flag) {
        this.isEnd = true;
        clearInterval(this.timer);
        this.addData();
        setTimeout(() => {
          this.show = true;
        }, 10);
      }
    },
  },
  computed: {
    ...mapState("setting", ["range", "level", "recordFail"]),
  },
  mounted() {
    this.init();
  },
  destroyed() {},
};
</script>

<style lang="less" scoped>
.time {
  position: absolute;
  top: 55px;
  right: 0;
  width: 20%;
  height: 30px;
  padding: 0 5px;
  text-align: center;
  font-size: 22px;
  color: red;
}
.type {
  position: absolute;
  left: 0;
  height: 30px;
  padding: 0 5px;
  font-size: 16px;
  color: #1989fa;
}
.GridRange {
  top: 55px;
}
.GridLevel {
  top: 85px;
}
.container {
  display: flex;
  flex-direction: column;
  margin-top: 150px;

  .row {
    display: flex;
    justify-content: center;
  }
}
.btnBox {
  position: absolute;
  bottom: 100px;
  display: flex;
  justify-content: center;
  width: 100%;

  .btn {
    width: 20%;
    padding: 5px;
    border: 1px solid #000;
    text-align: center;
    font-size: 28px;
  }

  .active {
    background: #999;
    color: #fff;
  }

  .pointer {
    color: #1989fa;
    border-right: 0;
  }
  .flag {
    color: red;
    border-left: 0;
  }
}
/deep/ .van-dialog__header {
  padding-top: 15px;
}

/deep/ .van-dialog__content {
  padding: 20px 0;

  .dialogInfo {
    margin-left: 10px;
    margin-top: 6px;
    color: #666;
  }
}
</style>
